package com.imooc.infra.repository.jdbc;

import com.imooc.util.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.DataClassRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;

import java.util.List;
import java.util.Map;

/**
 * @Author Tim
 * @Description:
 * @Version 1.0
 */
@Slf4j
@Component
public class DynamicJdbcRepository {

    private NamedParameterJdbcTemplate jdbcTemplate;
    private JdbcDataSourceTractionManager dataSourceTractionManager;

    public DynamicJdbcRepository(NamedParameterJdbcTemplate jdbcTemplate, JdbcDataSourceTractionManager dataSourceTractionManager) {
        this.jdbcTemplate = jdbcTemplate;
        this.dataSourceTractionManager = dataSourceTractionManager;
    }

    /**
     * 返回自定义的bean集合，参数传入map
     * @param sql
     * @param dataSource
     * @param resultType
     * @param args
     * @return
     * @param <T>
     */
    public <T>List<T> listBeans(String sql, String dataSource, Class<T> resultType, Map<String, Object> args) {
        DynamicDataSourceContextHolder.addDataSource(dataSource);
        List<T> beanList = jdbcTemplate.query(sql, args, new DataClassRowMapper(resultType));
        DynamicDataSourceContextHolder.removeCurrentDataSource();
        return beanList;
    }

    /**
     * 返回map集合，参数是map
     * @param content
     * @param dataSource
     * @param params
     * @return
     */
    public List<Map<String, Object>> queryMapList(String content, String dataSource, Map<String, Object> params) {
        DynamicDataSourceContextHolder.addDataSource(dataSource);
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(content, params);
        DynamicDataSourceContextHolder.removeCurrentDataSource();
        return maps;
    }

    public void saveAndDelete(String dataSource, String deleteSql, String insertSql, Map<String, Object> deleteParams, List<Map<String, Object>> results) {
        DynamicDataSourceContextHolder.addDataSource(dataSource);
        TransactionStatus status = null;
        try {
            //开启事务
            status = dataSourceTractionManager.begin();
            //执行删除数据指标sql
            jdbcTemplate.update(deleteSql, deleteParams);
            //批量插入
            jdbcTemplate.batchUpdate(insertSql, SqlParameterSourceUtils.createBatch(results.toArray()));
        } catch (Exception e){
            log.error("saveAndDelete, dataSource:{}, deleteSql:{},insertSql:{},params:{},  e=", dataSource,deleteSql,insertSql,deleteParams,e);
            //回滚事务
            dataSourceTractionManager.rollback(status);
        } finally {
            DynamicDataSourceContextHolder.removeCurrentDataSource();
        }
        //提交事务
        dataSourceTractionManager.commit(status);
    }

    public void execute(String dataSource, List<String> sqlList) {
        DynamicDataSourceContextHolder.addDataSource(dataSource);
        TransactionStatus status = null;
        try {
            //开启事务
            status = dataSourceTractionManager.begin();
            //批量插入
            jdbcTemplate.getJdbcTemplate().batchUpdate(sqlList.toArray(new String[]{}));
        } catch (Exception e){
            log.error("execute, dataSource:{}, sqlList:{},params:{},  e=", dataSource,sqlList,e);
            //回滚事务
            dataSourceTractionManager.rollback(status);
            throw e;
        } finally {
            DynamicDataSourceContextHolder.removeCurrentDataSource();
        }
        //提交事务
        dataSourceTractionManager.commit(status);
    }
}
